package com.cskaoyan.javase.oop2.encapsulate._2polymorphic._5exercise;
/**
 * 读程序题
 *
 * 怎么去查看一个"对象名.成员方法"的执行结果呢?
 *      1.首先看引用的数据类型
 *          如果引用是一个父类类型,那么这个引用会限制访问范围,这时能够访问的方法就只有父类,不要看子类
 *
 *      2.其次要看对象的数据类型
 *          尤其是父类引用指向子类对象时,要切记一旦子类中有方法的重写,这时调用这个方法,会体现出子类对行为
 *
 *  方法的重载以及就近原则
 *
 * @since 14:46
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new B();
        B b = new B();
        C c = new C();
        D d = new D();
        // 前三个引用都是父类引用,而且对象也是父类对象,所以全程只看父类,完全不要看子类,下面三次方法调用和子类一点关系都没有
        // AA
        System.out.println("1--" + a1.show(b));
        // AA
        System.out.println("2--" + a1.show(c));
        // AD
        System.out.println("3--" + a1.show(d));

        // BA
        System.out.println("4--" + a2.show(b));
        // BA
        System.out.println("5--" + a2.show(c));
        // AD
        System.out.println("6--" + a2.show(d));

        // BB
        System.out.println("7--" + b.show(b));

        // BB
        System.out.println("8--" + b.show(c));

        // AD
        System.out.println("9--" + b.show(d));
    }
}
// A类中两个方法是方法重载的关系
class A {
    // 该方法是父类独有的成员方法,没有被子类重写,但是会被子类继承
    public String show(D obj) {
        return ("A and D");
    }
    // 该方法是父子类共用的,且被子类重写
    public String show(A obj) {
        return ("A and A");
    }
}
// B类中两个方法也是方法重载的关系
class B extends A {
    // 该方法是子类独有的成员方法
    public String show(B obj) {
        return ("B and B");
    }
    // 该方法是重写自父类的一个方法,父子类中共有的方法
    @Override
    public String show(A obj) {
        return ("B and A");
    }
}
class C extends B {
}
class D extends B {
}